﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using wne.Context;

namespace wne.models


    { 
       public class strList
        {
            public string string1;
            public string string2;
            public strList()
            {
                string1 = "";
                string2 = "";
            }
        }




        /// <summary>
        /// Модель одной точки маршрута. Представляет собой набор её параметров.
        /// </summary>
        public class PointModel
        {
            public Context.Step Step;
            public List<Context.Step_Prm> Params = new List<Step_Prm>();
            //field_type
            //0-15 - как для групп
            //32-need
            //33-next т 
            //34-criteries
            public List<Context.Step_Field> Fields = new List<Step_Field>();
            //Field_Type-тип как в группах
        
        }

        /// <summary>
        /// Модель маршрута (пути)
        /// </summary>
        public class RouteModel
        {
            //список ключевых слов языка
            static string[] KEYWORDS = { "ROUTE", "STEP", "FIELDS", "CRITERIONS", "NEED", "NEXT", "IF", "PARAMETRS" };
            //список логических команд
            static string[] LOGICCMND = {"&&", "||", "!", "<", ">", ">=", "<=", "!=", "=="};
            //список типов
            static string[] TYPES = { "STRING", "NUMERICAL", "BOOL", "ONEOF", "MANYOF", "DATE", "FILE", "INT", "DOUBLE", "DOCFILE" };
            //список разделителей языка
            static string[] SEPARATORS = { " ", "\t", "\n", ".", "#", ":", "=" };
            //cписок заданных значений полей
            static string[] BOOLS = { "FALSE", "TRUE" };
            //список смысловых разделителей
            static string[] BRACKETS = { "{", "}", "(", ")" };

            public string _0(string s)
            {
                if (s[0] == '0') return "FALSE";
                else return "TRUE";

            }
            //проверка идентификаторов на соответствие правилам с помощью регулярных выражений
            static bool ifIdent(string str)
            {
                //идентификатор должен начинаться с заглавной латинской буквы
                //остальные символы или заглваные латинские буквы, или цифры, или "_", или "-"
                string pattern = "[A-Z]([A-Z]|[0-9]|_|-){" + (str.Length - 1) + "}";
                Regex regex = new Regex(pattern);
                Match match = regex.Match(str, 0, str.Length);
                return !String.IsNullOrEmpty(match.Value.ToString());
            }

            static bool ifStr(string str)
            {
                //идентификатор должен начинаться с заглавной латинской буквы
                //остальные символы или заглваные латинские буквы, или цифры, или "_", или "-"
                string pattern = "”(\\w|\\W){" + (str.Length - 2) + "}”";
                Regex regex = new Regex(pattern);
                Match match = regex.Match(str, 0, str.Length);
                return !String.IsNullOrEmpty(match.Value.ToString());
            }

            static bool ifCommand(string str)
            {
                //идентификатор должен начинаться с заглавной латинской буквы
                //остальные символы или заглваные латинские буквы, или цифры, или "_", или "-"
                string pattern = "_[A-Z]([A-Z]|[0-9]|_|-){" + (str.Length - 2) + "}";
                Regex regex = new Regex(pattern);
                Match match = regex.Match(str, 0, str.Length);
                return !String.IsNullOrEmpty(match.Value.ToString());
            }

            static bool ifNumb(string str)
            {
                string pattern = "((-[1-9][0-9]*)|[0-9]|[1-9][0-9]*){" + (str.Length) + "}";
                Regex regex = new Regex(pattern);

                Match match = regex.Match(str, 0, str.Length);
                return !String.IsNullOrEmpty(match.Value.ToString());
            }


            static string normalStringView(string str)
            {
                string s = str;
                s = s.ToUpper();
                s = s.TrimStart(' ', '\n', '\t');
                s = s.TrimEnd(' ', '\n', '\t') + ' ';



                string pattern = "{";
                Regex regex = new Regex(pattern);
                s = regex.Replace(s, " { ");


                pattern = "(\\s|\\n|\\t)(\\s|\\n|\\t)*";
                regex = new Regex(pattern);
                s = regex.Replace(s, " ");

                pattern = "}";
                regex = new Regex(pattern);
                s = regex.Replace(s, " } ");

                pattern = "\\(";
                regex = new Regex(pattern);
                s = regex.Replace(s, " ( ");

                pattern = "\\)";
                regex = new Regex(pattern);
                s = regex.Replace(s, " ) ");

                pattern = "(\\s|\\n|\\t)*=(\\s|\\n|\\t)*";
                regex = new Regex(pattern);
                s = regex.Replace(s, "=");



                pattern = ":: ";
                regex = new Regex(pattern);
                s = regex.Replace(s, ":FALSE:FALSE ");

                pattern = "::";
                regex = new Regex(pattern);
                s = regex.Replace(s, ":FALSE:");

                pattern = "(FALSE: )";
                regex = new Regex(pattern);
                s = regex.Replace(s, "FALSE:FALSE ");

                pattern = "(TRUE: )";
                regex = new Regex(pattern);
                s = regex.Replace(s, "TRUE:FALSE ");

                pattern = "(\\s|\\n|\\t)*:(\\s|\\n|\\t)*";
                regex = new Regex(pattern);
                s = regex.Replace(s, ":");


                pattern = "(\\s|\\n|\\t)(\\s|\\n|\\t)*";
                regex = new Regex(pattern);
                s = regex.Replace(s, " ");
                return s;
            }

            //функция проверки правильности расстановки скобок в строке str. ch1 - это вид открывающейся скобки, ch2 - вид закрывающейся скобки 
            //возвращает true, если всё верно. Иначе false.
            static bool bracketCheck(char ch1, char ch2, string str)
            {

                int q = 0; bool flag = true;
                if (ch1 == '{')
                {
                    foreach (char ch in str)
                    {
                        if ((ch == ch1) && (q <= 3))
                        {
                            q++;
                        }
                        else if ((ch == ch2) && (q <= 3))
                        {
                            q--;
                            if (q < 0) flag = false;
                        }
                    }
                }
                else
                {
                    foreach (char ch in str)
                    {
                        if ((ch == ch1))
                        {
                            q++;
                        }
                        else if ((ch == ch2))
                        {
                            q--;
                            if (q < 0) flag = false;
                        }
                    }
                }
                if ((flag == false) || (q > 0))
                    return false;
                else
                    return true;
            }




            public int RouteId; // айди маршрута
            public string RouteName; // название маршрута
            public List<Way_Prm> WayParams = new List<Way_Prm>(); // список параметров маршрута
            //field_type-как для групп
            public List<PointModel> Points = new List<PointModel>(); // список точек (шагов) маршрута
            public string RouteString = ""; // маршрут в в виде строки
            /// <summary>
            /// Метод трансформирует объект модели, для которой он вызван, в строку на скриптовом языке wnal
            /// для вывода на экран и, например, редактирования.
            /// 
            /// </summary>
            /// <returns>строку на скриптовом языке wnal.</returns>
            public String Transformation()
            {
                RouteString = "Route " + RouteName+ " {\n";
                RouteString = RouteString + "Parametrs {\n";
                foreach (Way_Prm wp in WayParams)
                {
                    RouteString = RouteString + wp.Prm_Name + "=" + wp.Prm_Value + "\n";

                }
                RouteString = RouteString + "}\n";

                foreach (PointModel pm in Points)
                {
                    RouteString = RouteString + "Step " + pm.Step.Step_Name+" {\n";

                    RouteString += "Parametrs {\n";
                    foreach (Step_Prm sp in pm.Params)
                    {
                        if (sp.Field_Type <= 15)
                        {
                            RouteString += sp.Prm_Name + "=" + sp.Prm_Value + "\n";
                        }
                    }
                    RouteString += "}\n";

                    RouteString += "Fields {\n";
                    foreach (Step_Field stf in pm.Fields)
                    {
                        RouteString += stf.Field_Name + ":" + TYPES[stf.Field_Type - 1] + ":" + _0(stf.Visible_Flag) + ":" + _0(stf.Editable_Falg) + "\n";
                    }
                    RouteString += "}\n";

                    foreach (Step_Prm sp in pm.Params)
                    {
                        if (sp.Field_Type ==  34)
                        {
                            RouteString += "Criterions {\n" +sp.Prm_Value + "\n}\n";
                        }
                        if (sp.Field_Type == 33)
                        {
                            RouteString += "Next {\n" + sp.Prm_Value + "\n}\n";
                        }
                        if (sp.Field_Type == 32)
                        {
                            RouteString += "Need#"+sp.Prm_Name+ " {\n" + sp.Prm_Value + "\n}\n";
                        }
                    }
                    RouteString += "}\n"; 

                    
                }
                RouteString = RouteString + "}";

                return RouteString; 
            }
            //переводит описание маршрута из модели маршрута в строку(как она выглядит в текстовом поле при редактировании)

            /// <summary>
            /// Конструктор маршрута. На вход получает строку на скриптовом языке wnal, парсит ее и собирает объект RouteModel.
            /// При получении на вход некорректной строки возвращает объект, поле RouteId которого равно -2 (RouteId=-2).
            /// </summary>
            /// <param name="pWnalTextbox">та самая строка</param>
            public RouteModel(String pWnalTextbox)
            {

                String route = pWnalTextbox;
                route = normalStringView(route);

                bool correct = false;
                //проверка на правильную расстановку фигурных скобок
                bool check = bracketCheck('{', '}', route);
                if (check == false)
                {
                    correct = true;
                }

                check = bracketCheck('(', ')', route);
                if (check == false)
                {
                    correct = true;
                }
                if (correct == false)
                {
                    List<string> lex = new List<string>();
                    List<string> lex2 = new List<string>();


                    strList tmpStr = new strList();

                    int pos2 = 0;
                    for (int pos = 0; pos < route.Length; pos++)
                    {
                        tmpStr.string2 = tmpStr.string2 + route[pos];

                        if (route[pos].ToString().Equals("("))
                        {
                            int level = 1;
                            pos2 = pos + 1;
                            while (level != 0)
                            {

                                tmpStr.string2 = tmpStr.string2 + route[pos2];
                                if (route[pos2].ToString().Equals("("))
                                    level++;
                                else if (route[pos2].ToString().Equals(")"))
                                    level--;
                                pos2++;
                            }

                            tmpStr.string1 = "TERM";
                            lex.Add(tmpStr.string1);
                            lex2.Add(tmpStr.string2);
                            tmpStr.string1 = "SEP";
                            tmpStr.string2 = route[pos2].ToString();
                            lex.Add(tmpStr.string1);
                            lex2.Add(tmpStr.string2);
                            tmpStr.string2 = "";
                            pos = pos2;


                        }
                        else
                        {
                            for (int i = 0; i < SEPARATORS.Length; i++)
                            {
                                if (route[pos].ToString().Equals(SEPARATORS[i]))
                                {
                                    tmpStr.string2 = tmpStr.string2.TrimEnd(' ', '\t', '\n', '.', '#', ':', '=');
                                    bool fl = false;

                                    if (fl == false)
                                    {
                                        for (int j = 0; j < KEYWORDS.Length; j++)
                                            if (tmpStr.string2.Equals(KEYWORDS[j]))
                                            {
                                                fl = true;
                                                tmpStr.string1 = "KEY";
                                            }
                                    }

                                    if (fl == false)
                                    {
                                        for (int j = 0; j < TYPES.Length; j++)
                                            if (tmpStr.string2.Equals(TYPES[j]))
                                            {
                                                fl = true;
                                                tmpStr.string1 = "TYPE";
                                            }
                                    }

                                    if (fl == false)
                                    {
                                        for (int j = 0; j < LOGICCMND.Length; j++)
                                            if (tmpStr.string2.Equals(LOGICCMND[j]))
                                            {
                                                fl = true;
                                                tmpStr.string1 = "LGC";
                                            }
                                    }

                                    if (fl == false)
                                    {
                                        for (int j = 0; j < BRACKETS.Length; j++)
                                            if (tmpStr.string2.Equals(BRACKETS[j]))
                                            {
                                                fl = true;
                                                tmpStr.string1 = "BRACK";
                                            }
                                    }

                                    if (fl == false)
                                    {
                                        for (int j = 0; j < BOOLS.Length; j++)
                                            if (tmpStr.string2.Equals(BOOLS[j]))
                                            {

                                                fl = true;
                                                tmpStr.string1 = "BOOLS";
                                            }

                                    }

                                    if (fl == false)
                                    {
                                        if (ifIdent(tmpStr.string2))
                                        {
                                            fl = true;
                                            tmpStr.string1 = "IDENT";
                                        }
                                    }

                                    if (fl == false)
                                    {
                                        if (ifNumb(tmpStr.string2))
                                        {
                                            fl = true;
                                            tmpStr.string1 = "NUMB";
                                        }
                                    }

                                    if (fl == false)
                                    {
                                        if (ifCommand(tmpStr.string2))
                                        {
                                            fl = true;
                                            tmpStr.string1 = "CMND";
                                        }
                                    }

                                    if (fl == false)
                                    {
                                        if (ifStr(tmpStr.string2))
                                        {
                                            fl = true;
                                            tmpStr.string1 = "STRNG";
                                        }
                                    }

                                    if (fl == true)
                                    {
                                        lex.Add(tmpStr.string1);
                                        lex2.Add(tmpStr.string2);
                                        tmpStr.string1 = "SEP";
                                        tmpStr.string2 = route[pos].ToString();
                                        lex.Add(tmpStr.string1);
                                        lex2.Add(tmpStr.string2);
                                        tmpStr.string2 = "";

                                        fl = false;

                                    }
                                    else
                                        correct = true;

                                }
                            }
                        }
                    }


                    if (correct == false)
                    {
                        string lvl = "";
                        int cnt, cnt2 = 0;
                        PointModel tmpPointModel = new PointModel();
                        Way_Prm tmpWay_Prm = new Way_Prm();
                        Step_Prm tmpStep_Prm = new Step_Prm();
                        Step_Field tmpStep_Field = new Step_Field();
                        Step tmpStep = new Step();

                        for (cnt = 0; cnt < lex.Count; cnt++)
                        {
                            if (lex[cnt].Equals("KEY"))
                            {
                                if (lex2[cnt].Equals("ROUTE") && lex[cnt + 1].Equals("SEP") && (lex[cnt + 2].Equals("IDENT")) && (lex[cnt + 3].Equals("SEP")) && (lex[cnt + 4].Equals("BRACK")) && (lex2[cnt + 4].Equals("{")))
                                {

                                    Way nWay = new Way();
                                    RouteName = lex2[cnt + 2];
                                    nWay.Way_Name = RouteName;


                                    lvl = "r"; cnt = cnt + 4;
                                }
                                else if (lex2[cnt].Equals("STEP") && lex[cnt + 1].Equals("SEP") && (lex[cnt + 2].Equals("IDENT")) && (lex[cnt + 3].Equals("SEP")) && (lex[cnt + 4].Equals("BRACK")) && (lex2[cnt + 4].Equals("{")))
                                {
                                    if (lvl.Equals("s")) Points.Add(tmpPointModel);
                                    tmpPointModel = new PointModel();

                                    tmpStep.Step_Name = lex2[cnt + 2];

                                    tmpPointModel.Step = new Step();
                                    tmpPointModel.Step.Step_Name = lex2[cnt+2];
                                    tmpPointModel.Step.Way_ID = RouteId;


                                    lvl = "s";
                                    cnt = cnt + 4;
                                }

                                else if (lex2[cnt].Equals("PARAMETRS") && (lex[cnt + 1].Equals("SEP")) && (lex[cnt + 2].Equals("BRACK")) && (lex2[cnt + 2].Equals("{")))
                                {
                                    if (lvl.Equals("r"))
                                    {
                                        cnt2 = cnt + 3;
                                        while (!lex2[cnt2].Equals("}"))
                                        {
                                            if (lex[cnt2].Equals("SEP") && (lex[cnt2 + 1].Equals("IDENT")) && (lex[cnt2 + 2].Equals("SEP")) && (lex2[cnt2 + 2].Equals("=")) && (lex[cnt2 + 3].Equals("NUMB")))
                                            {
                                                tmpWay_Prm.Prm_Name = lex2[cnt2 + 1];
                                                tmpWay_Prm.Prm_Value = lex2[cnt2 + 3];
                                                tmpWay_Prm.Way_ID = RouteId;

                                                cnt2 = cnt2 + 4;

                                                WayParams.Add(tmpWay_Prm);
                                                tmpWay_Prm = new Way_Prm();
                                            }
                                            else { cnt2 = cnt2 + 1; };
                                        }
                                        cnt = cnt2;
                                    }
                                    else if (lvl.Equals("s"))
                                    {
                                        cnt2 = cnt + 3;
                                        while (!lex2[cnt2].Equals("}"))
                                        {
                                            if (lex[cnt2].Equals("SEP") && (lex[cnt2 + 1].Equals("IDENT")) && (lex[cnt2 + 2].Equals("SEP")) && (lex2[cnt2 + 2].Equals("=")) && (lex[cnt2 + 3].Equals("NUMB")))
                                            {
                                                tmpStep_Prm.Prm_Name = lex2[cnt2 + 1];
                                                tmpStep_Prm.Prm_Value = lex2[cnt2 + 3];
                                                tmpStep_Prm.Step_ID = tmpStep.Step_ID;
                                                tmpStep_Prm.Field_Type = 1;

                                                cnt2 = cnt2 + 4;

                                                tmpPointModel.Params.Add(tmpStep_Prm);
                                                tmpStep_Prm = new Step_Prm();

                                            }
                                            else { cnt2 = cnt2 + 1; };
                                        }
                                        cnt = cnt2;
                                    }
                                }
                                else if (lex2[cnt].Equals("FIELDS") && lex[cnt + 1].Equals("SEP") && lex[cnt + 2].Equals("BRACK") && lex2[cnt + 2].Equals("{"))
                                {
                                    cnt2 = cnt + 3;
                                    while (!lex2[cnt2].Equals("}"))
                                    {
                                        if (lex[cnt2].Equals("SEP") && lex[cnt2 + 1].Equals("IDENT") && lex2[cnt2 + 2].Equals(":") && lex[cnt2 + 3].Equals("TYPE") && lex2[cnt2 + 4].Equals(":") && lex[cnt2 + 5].Equals("BOOLS") && lex2[cnt2 + 6].Equals(":") && lex[cnt2 + 7].Equals("BOOLS"))
                                        {

                                            tmpStep_Field.Step_ID = tmpStep.Step_ID;
                                            tmpStep_Field.Field_Name = lex2[cnt2 + 1];
                                            tmpStep_Field.Field_Type = (TYPES.ToList().IndexOf(lex2[cnt2 + 3]) + 1);
                                            tmpStep_Field.Visible_Flag = lex2[cnt2 + 5];
                                            tmpStep_Field.Editable_Falg = lex2[cnt2 + 7];



                                            cnt2 = cnt2 + 8;

                                            tmpPointModel.Fields.Add(tmpStep_Field);
                                            tmpStep_Field = new Step_Field();


                                        }
                                        else cnt2 = cnt2 + 1;

                                    }
                                    cnt = cnt2;
                                }
                                else if (lex2[cnt].Equals("CRITERIONS") && lex[cnt + 1].Equals("SEP") && lex2[cnt + 2].Equals("{"))
                                {
                                    cnt2 = cnt + 3;
                                    string critValue = "";
                                    while (!lex2[cnt2].Equals("}"))
                                    {
                                        critValue = critValue + lex2[cnt2++];

                                    }

                                    tmpStep_Prm.Prm_Name = "";
                                    tmpStep_Prm.Prm_Value = critValue;
                                    tmpStep_Prm.Step_ID = tmpStep.Step_ID;
                                    tmpStep_Prm.Field_Type = 34;


                                    tmpPointModel.Params.Add(tmpStep_Prm);
                                    tmpStep_Prm = new Step_Prm();

                                    cnt = cnt2;

                                }
                                else if (lex2[cnt].Equals("NEXT") && lex[cnt + 1].Equals("SEP") && lex2[cnt + 2].Equals("{"))
                                {
                                    cnt2 = cnt + 3;
                                    string critValue = "";
                                    while (!lex2[cnt2].Equals("}"))
                                    {
                                        critValue = critValue + lex2[cnt2++];

                                    }

                                    tmpStep_Prm.Prm_Name = "";
                                    tmpStep_Prm.Prm_Value = critValue;
                                    tmpStep_Prm.Step_ID = tmpStep.Step_ID;
                                    tmpStep_Prm.Field_Type = 33;


                                    tmpPointModel.Params.Add(tmpStep_Prm);
                                    tmpStep_Prm = new Step_Prm();
                                    cnt = cnt2;

                                }
                                else if (lex2[cnt].Equals("NEED") && lex2[cnt + 1].Equals("#") && lex[cnt + 2].Equals("IDENT") && lex[cnt + 3].Equals("SEP") && lex2[cnt + 4].Equals("{"))
                                {
                                    cnt2 = cnt + 5;
                                    string critValue = "";
                                    while (!lex2[cnt2].Equals("}"))
                                    {
                                        critValue = critValue + lex2[cnt2++];

                                    }
                                    tmpStep_Prm.Prm_Name = lex2[cnt + 2];
                                    tmpStep_Prm.Prm_Value = critValue;
                                    tmpStep_Prm.Step_ID = tmpStep.Step_ID;
                                    tmpStep_Prm.Field_Type = 32;


                                    tmpPointModel.Params.Add(tmpStep_Prm);
                                    tmpStep_Prm = new Step_Prm();
                                    cnt = cnt2;

                                }

                            }

                        }
                        if (lvl.Equals("s")) Points.Add(tmpPointModel);
                        tmpPointModel = new PointModel();
                    }
                    else
                        RouteId = -2;
                }
                else
                    RouteId = -2;
               
            }
            //то же самое, только не конструктор
            public void RouteModelFromString(String pWnalTextbox)
            {
                    WayParams = new List<Way_Prm>(); // список параметров маршрута
         
                    Points = new List<PointModel>(); // список точек (шагов) маршрута


                    String route = pWnalTextbox;
                    route = normalStringView(route);

                    bool correct = false;
                    //проверка на правильную расстановку фигурных скобок
                    bool check = bracketCheck('{', '}', route);
                    if (check == false)
                    {
                        correct = true;
                    }

                    check = bracketCheck('(', ')', route);
                    if (check == false)
                    {
                        correct = true;
                    }
                    if (correct == false)
                    {
                        List<string> lex = new List<string>();
                        List<string> lex2 = new List<string>();


                        strList tmpStr = new strList();

                        int pos2 = 0;
                        for (int pos = 0; pos < route.Length; pos++)
                        {
                            tmpStr.string2 = tmpStr.string2 + route[pos];

                            if (route[pos].ToString().Equals("("))
                            {
                                int level = 1;
                                pos2 = pos + 1;
                                while (level != 0)
                                {

                                    tmpStr.string2 = tmpStr.string2 + route[pos2];
                                    if (route[pos2].ToString().Equals("("))
                                        level++;
                                    else if (route[pos2].ToString().Equals(")"))
                                        level--;
                                    pos2++;
                                }

                                tmpStr.string1 = "TERM";
                                lex.Add(tmpStr.string1);
                                lex2.Add(tmpStr.string2);
                                tmpStr.string1 = "SEP";
                                tmpStr.string2 = route[pos2].ToString();
                                lex.Add(tmpStr.string1);
                                lex2.Add(tmpStr.string2);
                                tmpStr.string2 = "";
                                pos = pos2;


                            }
                            else
                            {
                                for (int i = 0; i < SEPARATORS.Length; i++)
                                {
                                    if (route[pos].ToString().Equals(SEPARATORS[i]))
                                    {
                                        tmpStr.string2 = tmpStr.string2.TrimEnd(' ', '\t', '\n', '.', '#', ':', '=');
                                        bool fl = false;

                                        if (fl == false)
                                        {
                                            for (int j = 0; j < KEYWORDS.Length; j++)
                                                if (tmpStr.string2.Equals(KEYWORDS[j]))
                                                {
                                                    fl = true;
                                                    tmpStr.string1 = "KEY";
                                                }
                                        }

                                        if (fl == false)
                                        {
                                            for (int j = 0; j < TYPES.Length; j++)
                                                if (tmpStr.string2.Equals(TYPES[j]))
                                                {
                                                    fl = true;
                                                    tmpStr.string1 = "TYPE";
                                                }
                                        }

                                        if (fl == false)
                                        {
                                            for (int j = 0; j < LOGICCMND.Length; j++)
                                                if (tmpStr.string2.Equals(LOGICCMND[j]))
                                                {
                                                    fl = true;
                                                    tmpStr.string1 = "LGC";
                                                }
                                        }

                                        if (fl == false)
                                        {
                                            for (int j = 0; j < BRACKETS.Length; j++)
                                                if (tmpStr.string2.Equals(BRACKETS[j]))
                                                {
                                                    fl = true;
                                                    tmpStr.string1 = "BRACK";
                                                }
                                        }

                                        if (fl == false)
                                        {
                                            for (int j = 0; j < BOOLS.Length; j++)
                                                if (tmpStr.string2.Equals(BOOLS[j]))
                                                {

                                                    fl = true;
                                                    tmpStr.string1 = "BOOLS";
                                                }

                                        }

                                        if (fl == false)
                                        {
                                            if (ifIdent(tmpStr.string2))
                                            {
                                                fl = true;
                                                tmpStr.string1 = "IDENT";
                                            }
                                        }

                                        if (fl == false)
                                        {
                                            if (ifNumb(tmpStr.string2))
                                            {
                                                fl = true;
                                                tmpStr.string1 = "NUMB";
                                            }
                                        }

                                        if (fl == false)
                                        {
                                            if (ifCommand(tmpStr.string2))
                                            {
                                                fl = true;
                                                tmpStr.string1 = "CMND";
                                            }
                                        }

                                        if (fl == false)
                                        {
                                            if (ifStr(tmpStr.string2))
                                            {
                                                fl = true;
                                                tmpStr.string1 = "STRNG";
                                            }
                                        }

                                        if (fl == true)
                                        {
                                            lex.Add(tmpStr.string1);
                                            lex2.Add(tmpStr.string2);
                                            tmpStr.string1 = "SEP";
                                            tmpStr.string2 = route[pos].ToString();
                                            lex.Add(tmpStr.string1);
                                            lex2.Add(tmpStr.string2);
                                            tmpStr.string2 = "";

                                            fl = false;

                                        }
                                        else
                                            correct = true;

                                    }
                                }
                            }
                        }


                        if (correct == false)
                        {
                            string lvl = "";
                            int cnt, cnt2 = 0;
                            PointModel tmpPointModel = new PointModel();
                            Way_Prm tmpWay_Prm = new Way_Prm();
                            Step_Prm tmpStep_Prm = new Step_Prm();
                            Step_Field tmpStep_Field = new Step_Field();
                            Step tmpStep = new Step();

                            for (cnt = 0; cnt < lex.Count; cnt++)
                            {
                                if (lex[cnt].Equals("KEY"))
                                {
                                    if (lex2[cnt].Equals("ROUTE") && lex[cnt + 1].Equals("SEP") && (lex[cnt + 2].Equals("IDENT")) && (lex[cnt + 3].Equals("SEP")) && (lex[cnt + 4].Equals("BRACK")) && (lex2[cnt + 4].Equals("{")))
                                    {

                                        Way nWay = new Way();
                                        RouteName = lex2[cnt + 2];
                                        nWay.Way_Name = RouteName;


                                        lvl = "r"; cnt = cnt + 4;
                                    }
                                    else if (lex2[cnt].Equals("STEP") && lex[cnt + 1].Equals("SEP") && (lex[cnt + 2].Equals("IDENT")) && (lex[cnt + 3].Equals("SEP")) && (lex[cnt + 4].Equals("BRACK")) && (lex2[cnt + 4].Equals("{")))
                                    {
                                        if (lvl.Equals("s")) Points.Add(tmpPointModel);
                                        tmpPointModel = new PointModel();

                                        tmpStep.Step_Name = lex2[cnt + 2];

                                        tmpPointModel.Step = new Step();
                                        tmpPointModel.Step.Step_Name = lex2[cnt + 2];
                                        tmpPointModel.Step.Way_ID = RouteId; 

                                        lvl = "s";
                                        cnt = cnt + 4;
                                    }

                                    else if (lex2[cnt].Equals("PARAMETRS") && (lex[cnt + 1].Equals("SEP")) && (lex[cnt + 2].Equals("BRACK")) && (lex2[cnt + 2].Equals("{")))
                                    {
                                        if (lvl.Equals("r"))
                                        {
                                            cnt2 = cnt + 3;
                                            while (!lex2[cnt2].Equals("}"))
                                            {
                                                if (lex[cnt2].Equals("SEP") && (lex[cnt2 + 1].Equals("IDENT")) && (lex[cnt2 + 2].Equals("SEP")) && (lex2[cnt2 + 2].Equals("=")) && (lex[cnt2 + 3].Equals("NUMB")))
                                                {
                                                    tmpWay_Prm.Prm_Name = lex2[cnt2 + 1];
                                                    tmpWay_Prm.Prm_Value = lex2[cnt2 + 3];
                                                    tmpWay_Prm.Way_ID = RouteId;

                                                    cnt2 = cnt2 + 4;

                                                    WayParams.Add(tmpWay_Prm);
                                                    tmpWay_Prm = new Way_Prm();
                                                }
                                                else { cnt2 = cnt2 + 1; };
                                            }
                                            cnt = cnt2;
                                        }
                                        else if (lvl.Equals("s"))
                                        {
                                            cnt2 = cnt + 3;
                                            while (!lex2[cnt2].Equals("}"))
                                            {
                                                if (lex[cnt2].Equals("SEP") && (lex[cnt2 + 1].Equals("IDENT")) && (lex[cnt2 + 2].Equals("SEP")) && (lex2[cnt2 + 2].Equals("=")) && (lex[cnt2 + 3].Equals("NUMB")))
                                                {
                                                    tmpStep_Prm.Prm_Name = lex2[cnt2 + 1];
                                                    tmpStep_Prm.Prm_Value = lex2[cnt2 + 3];
                                                    tmpStep_Prm.Step_ID = tmpStep.Step_ID;
                                                    tmpStep_Prm.Field_Type = 1;

                                                    cnt2 = cnt2 + 4;

                                                    tmpPointModel.Params.Add(tmpStep_Prm);
                                                    tmpStep_Prm = new Step_Prm();

                                                }
                                                else { cnt2 = cnt2 + 1; };
                                            }
                                            cnt = cnt2;
                                        }
                                    }
                                    else if (lex2[cnt].Equals("FIELDS") && lex[cnt + 1].Equals("SEP") && lex[cnt + 2].Equals("BRACK") && lex2[cnt + 2].Equals("{"))
                                    {
                                        cnt2 = cnt + 3;
                                        while (!lex2[cnt2].Equals("}"))
                                        {
                                            if (lex[cnt2].Equals("SEP") && lex[cnt2 + 1].Equals("IDENT") && lex2[cnt2 + 2].Equals(":") && lex[cnt2 + 3].Equals("TYPE") && lex2[cnt2 + 4].Equals(":") && lex[cnt2 + 5].Equals("BOOLS") && lex2[cnt2 + 6].Equals(":") && lex[cnt2 + 7].Equals("BOOLS"))
                                            {

                                                tmpStep_Field.Step_ID = tmpStep.Step_ID;
                                                tmpStep_Field.Field_Name = lex2[cnt2 + 1];
                                                tmpStep_Field.Field_Type = (TYPES.ToList().IndexOf(lex2[cnt2 + 3]) + 1);
                                                tmpStep_Field.Visible_Flag = lex2[cnt2 + 5];
                                                tmpStep_Field.Editable_Falg = lex2[cnt2 + 7];



                                                cnt2 = cnt2 + 8;

                                                tmpPointModel.Fields.Add(tmpStep_Field);
                                                tmpStep_Field = new Step_Field();


                                            }
                                            else cnt2 = cnt2 + 1;

                                        }
                                        cnt = cnt2;
                                    }
                                    else if (lex2[cnt].Equals("CRITERIONS") && lex[cnt + 1].Equals("SEP") && lex2[cnt + 2].Equals("{"))
                                    {
                                        cnt2 = cnt + 3;
                                        string critValue = "";
                                        while (!lex2[cnt2].Equals("}"))
                                        {
                                            critValue = critValue + lex2[cnt2++];

                                        }

                                        tmpStep_Prm.Prm_Name = "";
                                        tmpStep_Prm.Prm_Value = critValue;
                                        tmpStep_Prm.Step_ID = tmpStep.Step_ID;
                                        tmpStep_Prm.Field_Type = 34;


                                        tmpPointModel.Params.Add(tmpStep_Prm);
                                        tmpStep_Prm = new Step_Prm();

                                        cnt = cnt2;

                                    }
                                    else if (lex2[cnt].Equals("NEXT") && lex[cnt + 1].Equals("SEP") && lex2[cnt + 2].Equals("{"))
                                    {
                                        cnt2 = cnt + 3;
                                        string critValue = "";
                                        while (!lex2[cnt2].Equals("}"))
                                        {
                                            critValue = critValue + lex2[cnt2++];

                                        }

                                        tmpStep_Prm.Prm_Name = "";
                                        tmpStep_Prm.Prm_Value = critValue;
                                        tmpStep_Prm.Step_ID = tmpStep.Step_ID;
                                        tmpStep_Prm.Field_Type = 33;
 

                                        tmpPointModel.Params.Add(tmpStep_Prm);
                                        tmpStep_Prm = new Step_Prm();
                                        cnt = cnt2;

                                    }
                                    else if (lex2[cnt].Equals("NEED") && lex2[cnt + 1].Equals("#") && lex[cnt + 2].Equals("IDENT") && lex[cnt + 3].Equals("SEP") && lex2[cnt + 4].Equals("{"))
                                    {
                                        cnt2 = cnt + 5;
                                        string critValue = "";
                                        while (!lex2[cnt2].Equals("}"))
                                        {
                                            critValue = critValue + lex2[cnt2++];

                                        }
                                        tmpStep_Prm.Prm_Name = lex2[cnt+2];
                                        tmpStep_Prm.Prm_Value = critValue;
                                        tmpStep_Prm.Step_ID = tmpStep.Step_ID;
                                        tmpStep_Prm.Field_Type = 32;


                                        tmpPointModel.Params.Add(tmpStep_Prm);
                                        tmpStep_Prm = new Step_Prm();
                                        cnt = cnt2;

                                    }

                                }

                            }
                            if (lvl.Equals("s")) Points.Add(tmpPointModel);
                            tmpPointModel = new PointModel();
                        } else
                        RouteId = -2;
                    } else
                    RouteId = -2;
                
            }
            /// <summary>
            /// Инициализирует объект маршрута для вывода на экран, для нового маршрута.
            /// </summary>
            public RouteModel()
            {
                
            }

        }
}
